import gradio as gr
from tools.lol.text_to_image import text_to_image
from tools.lol.text_to_image import image_dir
import os
from tools.lol.text_to_image import conv_str_ls_to_ss
import shutil
from pyperclip import copy, paste
import pandas as pd
from tools.my_gr_tools import my_gr_assert_function
import keyboard
from tools.lol.send_to import send_str_ls


hot_key = 'alt+f2'


def upload_file(files):
    if isinstance(files, str):
        return files
    file_paths = [file.name for file in files]
    return file_paths


choices = os.listdir(image_dir)
examples = [os.path.join(image_dir, img_name) for img_name in os.listdir(image_dir)]

combine_ls = list(zip(examples, choices))


css = "#output_result {font-family: 'YouYuan' !important;white-space: normal !important;}"

# with gr.Blocks() as demo:
with gr.Blocks(css=css) as demo:
    # gr.Markdown("# 像素生成")
    gr.Markdown("# Test")

    output_files = []


    def on_click(image_path, text, font_size, threshold, use_cache, auto_copy):  # SelectData is a subclass of EventData
        global output_files
        # global _use_cache

        # print('params:', params)

        if image_path is not None and not isinstance(image_path, str):
            image_path = None

        if image_path is None and not text:
            raise gr.Error("image_path和text不能全为空!")

        _output_files = []
        if image_path is not None:
            str_ls, _output_file = text_to_image(image_path=image_path, font_size=font_size, threshold=threshold, use_cache=use_cache)
            _output_files.append(_output_file)
        else:
            text = text.replace("；", ';')
            text = text.replace(" ", ';')

            if ';' in text:
                text = text.split(';')

            str_ls = []
            for t in text:
                # break
                if not t:
                    continue
                _str_ls, _output_file = text_to_image(t, font_size=font_size, threshold=threshold, use_cache=use_cache)
                _output_files.append(_output_file)

                ss = '\n'.join([''.join(ls) for ls in _str_ls])
                str_ls.append(ss)

        output_files = _output_files
        ss = conv_str_ls_to_ss(str_ls)

        if auto_copy:
            copy(ss)
        return ss


    def conv_image_to_pixel_style(image_path):
        str_ls, _ = text_to_image(image_path=image_path, font_size=16, threshold=254)

        ss = conv_str_ls_to_ss(str_ls)
        return ss


    with gr.Row():
        with gr.Column(scale=2):
            with gr.Accordion("生成参数模块", open=True):
                font_size = gr.Slider(1, 16, value=11, step=1, label="font_size", info="生成结果的大小, 建议10~11")
                threshold = gr.Slider(1, 254, value=175, step=1, label="threshold",
                                      info="像素显示的阈值, text推荐175, image推荐205~254")

            with gr.Tabs(visible=True, selected="tab_1") as tabs1:
                state = gr.State("tab_1")
                last_selected_tab = 'tab_1'

                with gr.Tab("文字输入", id='tab_1') as tab_1:
                    import os

                    user_data_dir = '../tempdir/data/user'
                    os.makedirs(user_data_dir, exist_ok=True)

                    text_choices_path = os.path.join(user_data_dir, 'common_text.txt')


                    def save_choices(text_choices_value, text_choices_path):
                        with open(text_choices_path, 'w+') as f:
                            new_ls = [i for i in text_choices_value if i not in ['', None, '\n', []]]
                            s = '\n'.join(new_ls)
                            f.write(s)


                    def load_text_choices():
                        _text_choices = ["", "20;", "GG;", "草", '20;投', '草;你;妈']
                        if not os.path.exists(text_choices_path):
                            text_choices = _text_choices
                            return text_choices
                        else:
                            with open(text_choices_path, 'r') as f:
                                text_choices = f.readlines()

                        text_choices = [t.strip() for t in text_choices if t not in ['', None, '\n', []]]
                        if not text_choices:
                            text_choices = _text_choices
                        return text_choices


                    text_choices = load_text_choices()


                    init_text_value = 'GG;'
                    def text_dropdown_generator(the_choices, value=None):
                        value = value if value is not None else init_text_value
                        res = gr.Dropdown(
                            the_choices, label="文字", info="文转像素, 有`;`号或者空格则会启用合并输出功能",
                            multiselect=False, allow_custom_value=True,
                            value=value
                        )
                        return res


                    text = text_dropdown_generator(the_choices=text_choices)


                    def on_change__text():  # on_select
                        global last_selected_tab
                        global threshold

                        _threshold = 175 if last_selected_tab == 'tab_2' else threshold

                        last_selected_tab = 'tab_1'

                        return None, None, _threshold


                    with gr.Column():
                        gr.Markdown("常用选项管理")
                        with gr.Row():
                            def add_to_history_1(_text):
                                global text_choices
                                global text

                                if _text in text_choices:
                                    gr.Warning(f"请勿重复添加[{_text}]!")
                                    return _text
                                text_choices = text_choices + [_text]
                                save_choices(text_choices, text_choices_path)

                                text = text_dropdown_generator(text_choices, _text)
                                return text


                            def remove_from_history_1(_text):
                                global text_choices

                                if _text not in text_choices:
                                    gr.Warning(f"常用文本中不存在[{_text}]!")
                                    return _text

                                if len(text_choices) <= 1:
                                    gr.Warning(f"常用文本数量不能为0!")
                                    return _text

                                text_choices.remove(_text)
                                save_choices(text_choices, text_choices_path)
                                text = text_dropdown_generator(text_choices)
                                return text


                            btn_add_to_history_1 = gr.Button('添加到常用', size='sm', min_width=111)
                            btn_remove_from_history_1 = gr.Button('从常用删除', size='sm', min_width=111)

                            btn_add_to_history_1.click(add_to_history_1, inputs=[text], outputs=[text])
                            btn_remove_from_history_1.click(remove_from_history_1, inputs=[text],
                                                            outputs=[text])

                with gr.Tab("图片输入", id='tab_2') as tab_2:
                    with gr.Row():
                        from tools.lol.tk_uploader import tk_asksavefile_asy

                        # text_dropdown_generator
                        with gr.Column(scale=1):
                            norm_input_btn = gr.Button('上传本地图片')
                            image_choices = list(zip(choices, examples))


                            def image_dropdown_generator(the_choices, value=None):
                                res = gr.Dropdown(
                                    the_choices, label="图片路径", info="图片转像素图",
                                    multiselect=False, allow_custom_value=True,
                                    value=value
                                )
                                return res

                            input_image_path = image_dropdown_generator(image_choices, value=None)

                            with gr.Column():
                                gr.Markdown("常用选项管理")
                                with gr.Row():
                                    btn_add_to_history = gr.Button('添加到常用', size='sm', min_width=111)
                                    btn_remove_from_history = gr.Button('从常用删除', size='sm', min_width=111)


                            def on_select(text, threshold, evt: gr.SelectData):  # on_select
                                global last_selected_tab

                                _threshold = 205 if last_selected_tab == 'tab_1' else threshold

                                last_selected_tab = 'tab_2'

                                image_path = image_choices[evt.index][-1]
                                return image_path, _threshold


                            def add_to_history(_input_image_path):
                                global input_image_path
                                global preview_image
                                global image_choices, choices

                                if not _input_image_path:
                                    gr.Warning(f"请先选择图片!")
                                    return input_image_path

                                base_name = os.path.basename(_input_image_path)

                                if base_name in choices:
                                    gr.Warning(f"文件名[{base_name}]重复!")
                                    # raise gr.Error(f"文件名[{base_name}]重复!")
                                    return input_image_path

                                new_path = os.path.join(image_dir, base_name)
                                shutil.copy2(_input_image_path, new_path)

                                image_choices.append((base_name, new_path))
                                choices.append(base_name)

                                new_dropdown = image_dropdown_generator(image_choices, value=base_name)
                                return new_dropdown


                            def remove_from_history(_input_image_path):
                                global input_image_path
                                global preview_image
                                global image_choices, choices

                                if len(choices) <= 1:
                                    gr.Warning(f"常用文件数量不能为0!")
                                    return image_choices, preview_image

                                if not _input_image_path:
                                    gr.Warning(f"请先选择图片!")
                                else:
                                    if os.path.isabs(_input_image_path):
                                        gr.Warning(f"不是常用文件!")
                                        return image_choices, preview_image
                                    else:
                                        if not _input_image_path.startswith('data'):
                                            _input_image_path = os.path.join(image_dir, _input_image_path)

                                    base_name = os.path.basename(_input_image_path)

                                    if base_name not in choices and not os.path.exists(_input_image_path):
                                        gr.Warning(f"文件名[{base_name}]已不存在!")
                                    else:
                                        try:
                                            os.remove(_input_image_path)
                                        except Exception as e:
                                            print("***** Error:", e)
                                            raise e

                                        index = choices.index(base_name)
                                        choices.pop(index)
                                        image_choices.pop(index)

                                new_dropdown = image_dropdown_generator(image_choices)
                                return new_dropdown, None

                        preview_image = gr.Image(label="预览")

                        # tabs1.change(on_change__text, [], [input_image_path, preview_image, threshold])
                        text.change(on_change__text, [], [input_image_path, preview_image, threshold])
                        text.select(on_change__text, [], [input_image_path, preview_image, threshold])
                        input_image_path.select(on_select, [text, threshold], [preview_image, threshold])
                        norm_input_btn.click(tk_asksavefile_asy, inputs=[], outputs=[input_image_path, preview_image])
                        btn_add_to_history.click(add_to_history, inputs=[input_image_path], outputs=[input_image_path])
                        btn_remove_from_history.click(remove_from_history, inputs=[input_image_path],
                                                      outputs=[input_image_path, preview_image])

        with gr.Column(scale=1):
            btn = gr.Button("生成")

            with gr.Row():
                checkbox__send_all = gr.Checkbox(label="send_all", value=True, info="发送给所有人?", min_width=100)
                use_cache = gr.Checkbox(label="use_cache", value=True, info="使用缓存?", min_width=100)
                auto_copy = gr.Checkbox(label="auto_copy", value=True, info="自动复制?", min_width=100)

                # selects = gr.CheckboxGroup(["send_all", "use_cache", "save_params"], label="Countries", info="Where are they from?")
                # params = gr.CheckboxGroup([("A", 'send_all'), ('B', 'use_cache'), ('C', 'save_params')], label="参数", info="哈哈哈哈")

            with gr.Row():
                save_btn = gr.Button("保存结果", min_width=50)
                clear_cache = gr.Button("清除缓存", min_width=50)

                def f_clear_cache():
                    from tools.lol.text_to_image import output_dir
                    from tools.remove_temp_file import remove_path
                    remove_path(output_dir, keep_external_folder=True)
                    gr.Info("清除缓存成功!")

                def save_custom_text(statement):
                    global output_files

                    if my_gr_assert_function(output_files and statement, '输出不为空才能保存...', status='warning'):
                        return

                    output_file_i = output_files[0]
                    f_name = os.path.splitext(os.path.basename(output_file_i))[0]
                    v_name, _, font_size, threshold = f_name.split('_')
                    font_size = int(font_size)

                    os.makedirs(os.path.dirname(output_file_i), exist_ok=True)

                    str_ls = statement.split('\n')

                    f_i = 0
                    for i in range(0, len(str_ls), font_size):
                        if f_i >= len(output_files):
                            break
                        output_file = output_files[f_i]
                        f_i += 1

                        ss = '\n'.join(str_ls[i: i + font_size])

                        with open(output_file, 'w+', encoding='utf-8') as f:
                            f.write(ss)

                        # print(ss)
                        # print('-' * 30 + ' ' + output_file)

                    gr.Info("处理成功~")

            ouput_result = gr.Textbox(label="输出结果", show_copy_button=True, interactive=True, elem_id='output_result', info=f"可自定义编辑并保存, [{hot_key}]将自动输出剪切板内容")
            save_btn.click(save_custom_text, [ouput_result])
            clear_cache.click(f_clear_cache)

            send_all = True
            _use_cache = False


            def change_send_all(checkbox__send_all):
                global send_all
                # print(send_all, '-->', checkbox__send_all)
                send_all = checkbox__send_all
                return send_all


            checkbox__send_all.change(change_send_all, checkbox__send_all, checkbox__send_all)

            parameters_df_path = os.path.join(user_data_dir, 'parameters_df.csv')
            if os.path.exists(parameters_df_path):
                parameters_df = pd.read_csv(parameters_df_path)
            else:
                parameters_df = pd.DataFrame(
                    [
                        ['初始间隔时间', 0.5],
                        ['整字间隔时间', 0.25],
                        ['每行间隔时间', 0.15]
                    ],
                    columns=['Key', 'Value'],
                )
                parameters_df.to_csv(parameters_df_path, index=False)
            intervals = parameters_df['Value'].tolist()

            with gr.Accordion("速度参数模块", open=False):
                g__df = gr.Dataframe(value=parameters_df, label="速度参数表")


            def on_g_df_change(g__df):
                global intervals
                global parameters_df

                # print('--- on_g_df_change')
                _intervals = g__df['Value'].tolist()
                for i in range(len(_intervals)):
                    it = _intervals[i]
                    try:
                        it = float(it)
                        intervals[i] = it
                    except:
                        raise gr.Error(f"第[{i}]行的[{it}]无法转换为数值! type: {type(it)}")
                # intervals = _intervals
                parameters_df = g__df
                parameters_df.to_csv(parameters_df_path, index=False)


            g__df.change(on_g_df_change, g__df)

            btn.click(on_click, [input_image_path, text, font_size, threshold, use_cache, auto_copy], outputs=ouput_result)


            # btn_refresh = gr.Button(value="选择标签2")
            # btn_refresh.click(None, js="window.location.reload();console.log(123);")

            def refresh_selected_tab(state):  # on_select
                state = last_selected_tab
                return [gr.update(selected=state), state]
            # btn_refresh.click(fn=refresh_selected_tab, inputs=state, outputs=[tabs1, state])


        def refresh_text_choices():
            global text
            global parameters_df
            global intervals

            text = text_dropdown_generator(the_choices=text_choices)
            input_image_path = image_dropdown_generator(image_choices)

            g__df = parameters_df = pd.read_csv(parameters_df_path)
            intervals = parameters_df['Value'].tolist()
            return text, input_image_path, g__df


        demo.load(fn=refresh_text_choices, inputs=None, outputs=[text, input_image_path, g__df],
                  show_progress=False,
                  trigger_mode='once',
                  )
        demo.load(fn=refresh_selected_tab, inputs=state, outputs=[tabs1, state],
                  show_progress=False,
                  trigger_mode='once',
                  )


def auto_paste_from_clip():
    global send_all
    global _use_cache
    global intervals

    ss = paste()

    # # --- 长文本处理
    # for o in ['。', '?', '？', '!', '！']:
    #     ss = ss.replace(o, f"{o}\n")

    str_ls = ss.split('\n')
    send_str_ls(str_ls, send_all=send_all, interval_1=intervals[0], interval_2=intervals[1], interval_3=intervals[2])


keyboard.add_hotkey(hot_key, auto_paste_from_clip)

# demo.load(refresh_text_choices)
demo.launch()
